import LifeModel from "../schema/life";
import { Request, Response } from "express";
import Types from "../typings";

// Common 类的实例
import Common from "./common";
const LifeCommonIns = new Common(LifeModel);

// 响应类型实例
import ResType from "./resType";
const ResTypeIns = new ResType();

interface SearchQueryType {
  [propName: string]: any;
  creatorId: string;
  page: number;
  size: number;
  level: string;
  title: any;
  isFinish: boolean | string;
}

class Life {
  constructor() {}

  // 查看用户列表
  async list(req: Request, res: Response) {
    try {
      const creatorId = LifeCommonIns.getLoginUserId(
        req as Types.Express.ConvertRequest
      );
      let {
        page = 1,
        size = 10,
        title = "",
        level = "",
        isFinish = "",
        startTime = "",
        endTime = "",
      } = req.query as Partial<SearchQueryType>;
      page = Number(page);
      size = Number(size);

      const query: Partial<SearchQueryType> = {
        creatorId,
      };

      // 搜索条件
      title && (query.title = { $regex: title, $options: "i" });
      level && (query.level = <string>level);

      // 默认查询未完成的数据
      if ([true, "true", false, "false"].includes(isFinish)) {
        query.isFinish = String(isFinish);
      }

      if (startTime && endTime) {
        query.createdTime = { $gte: startTime, $lte: endTime };
      }

      // 总条数
      const total = await LifeCommonIns.Count(query);

      // 查询数据
      const lifes: Types.Life.LifeType[] = await LifeCommonIns.Find(query)
        .skip(size * (page - 1))
        .limit(size)
        .sort({
          isTop: -1,
          level: 1,
          createdTime: -1,
        });

      const data = {
        page,
        size,
        list: lifes,
        total,
      };

      ResTypeIns.Success(res, data);
    } catch (err) {
      ResTypeIns.Database(res, err);
    }
  }

  // 查看单个用户
  async check(req: Request, res: Response) {
    try {
      let { id } = req.query;

      if (!id) {
        ResTypeIns.paramsWrong(res);
      } else {
        // 查询用户数据
        const lifes: Types.Life.LifeType[] = await LifeCommonIns.Find({
          id,
        });

        if (!lifes.length) {
          // 用户不存在
          ResTypeIns.isNotExist(res);
        } else {
          // 用户存在时
          ResTypeIns.Success(res, lifes[0]);
        }
      }
    } catch (err) {
      ResTypeIns.Database(res, err);
    }
  }

  // 新增用户
  async add(req: Request, res: Response) {
    try {
      const creatorId = LifeCommonIns.getLoginUserId(
        req as Types.Express.ConvertRequest
      );

      const { title, content, level, isFinish, isTop } = req.body;

      const lifes: Types.Life.LifeType[] = await LifeCommonIns.Find({
        title,
      });

      if (lifes.length) {
        ResTypeIns.isExist(res);
      } else {
        await LifeCommonIns.SaveOne({
          title,
          content,
          level,
          isFinish,
          isTop,
          creatorId,
          createdTime: Date.now(),
          updatedTime: Date.now(),
        });

        ResTypeIns.Success(res);
      }
    } catch (err) {
      ResTypeIns.Database(res, err);
    }
  }

  // 更新用户信息
  async update(req: Request, res: Response) {
    try {
      const { id, title, content, level, isFinish, isTop } = <
        Partial<Types.Life.LifeType>
      >req.body;
      if (!id) {
        ResTypeIns.paramsWrong(res);
      } else {
        const updateContent = {
          title,
          content,
          level,
          isFinish,
          isTop,
          updatedTime: Date.now(),
        };

        await LifeCommonIns.UpdateOne({ id }, updateContent);
        ResTypeIns.Success(res);
      }
    } catch (err) {
      ResTypeIns.Database(res, err);
    }
  }

  // 删除单个用户
  async remove(req: Request, res: Response) {
    try {
      let { id } = req.query;

      if (!id) {
        ResTypeIns.paramsWrong(res);
      } else {
        // 删除用户数据
        await LifeCommonIns.RemoveOne({ id });

        ResTypeIns.Success(res);
      }
    } catch (err) {
      ResTypeIns.Database(res, err);
    }
  }

  // 完成待办
  async finish(req: Request, res: Response) {
    try {
      const { id, isFinish = false } = <Partial<Types.Life.LifeType>>req.body;
      if (!id) {
        ResTypeIns.paramsWrong(res);
      } else {
        const updateContent = {
          isFinish,
          updatedTime: Date.now(),
        };

        await LifeCommonIns.UpdateOne({ id }, updateContent);
        ResTypeIns.Success(res);
      }
    } catch (err) {
      ResTypeIns.Database(res, err);
    }
  }

  // 置顶、取消置顶
  async setTop(req: Request, res: Response) {
    try {
      const { id, isTop = false } = <Partial<Types.Life.LifeType>>req.body;
      if (!id) {
        ResTypeIns.paramsWrong(res);
      } else {
        const updateContent = {
          isTop,
          updatedTime: Date.now(),
        };

        await LifeCommonIns.UpdateOne({ id }, updateContent);
        ResTypeIns.Success(res);
      }
    } catch (err) {
      ResTypeIns.Database(res, err);
    }
  }

  // 批量操作
  async batch(req: Request, res: Response) {
    try {
      const { ids, type } = <
        {
          ids: string;
          type: "" | "delete" | "finish" | "top" | "cancelTop" | "cancelFinish";
        }
      >req.body;

      if (!ids || !type) {
        ResTypeIns.paramsWrong(res);
      } else if (type === "delete") {
        await LifeCommonIns.DeleteMany({ id: { $in: ids.split(",") } });
        ResTypeIns.Success(res);
      } else {
        const updateData: Partial<Types.Life.LifeType> = {};
        if (type === "top") {
          updateData.isTop = true;
        } else if (type === "cancelTop") {
          updateData.isTop = false;
        } else if (type === "finish") {
          updateData.isFinish = true;
        } else if (type === "cancelFinish") {
          updateData.isFinish = false;
        }

        await LifeCommonIns.updateMany(
          { id: { $in: ids.split(",") } },
          updateData
        );

        ResTypeIns.Success(res);
      }
    } catch (err) {
      ResTypeIns.Database(res, err);
    }
  }
}
export default Life;
